package com.huawei.cloud.phone.management.domain.user;

import com.huawei.cloud.phone.management.common.exception.AuthFailedException;
import com.huawei.cloud.phone.management.common.exception.LoginFailedException;
import com.huawei.cloud.phone.management.common.exception.UserRepeatException;
import com.huawei.cloud.phone.management.domain.cache.CacheResource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Slf4j
@AllArgsConstructor
@Component
public class UserDomainService {
    private final UserGateway userGateWay;

    private final CacheResource<User> tokenCache;

    private final CacheResource<String> userCache;

    private final UserEventPublish userEventPublish;

    /**
     * 用户注册，用户名重复时报错
     *
     * @param user 用户信息
     */
    public void register(User user) {
        user.handleSensitiveInfo();

        Optional<User> savedUser = userGateWay.saveUser(user);
        if (!savedUser.isPresent()) {
            throw new UserRepeatException(user.getUsername());
        }

        // 注册成功，发布新增用户事件
        userEventPublish.addUser(savedUser.get().getUserId());
    }

    /**
     * 用户登录
     *
     * @param user 用户信息
     * @return 登录信息
     */
    public User login(User user) {
        user.handleSensitiveInfo();
        Optional<User> userOptional = userGateWay.getUser(user.getUsername(), user.getPassword());

        if (!userOptional.isPresent()) {
            throw new LoginFailedException(user.getUsername());
        }
        if (userCache.getData(user.getUsername()).isPresent()) {
            forceLogout(user.getUsername());
        }

        User userEntity = userOptional.get();
        userEntity.genLoginInfo();
        userCache.cacheData(user.getUsername(), userEntity.getSessionId());
        tokenCache.cacheData(userEntity.getSessionId(), userEntity);
        return userEntity;
    }

    /**
     * 用户退出登录
     *
     * @param sessionId 登录的session id
     */
    public void logout(String sessionId) {
        Optional<User> user = tokenCache.getData(sessionId);
        if (user.isPresent()) {
            tokenCache.clearData(sessionId);
            userCache.clearData(user.get().getUsername());
        }
    }

    /**
     * 用户退出登录
     *
     * @param username 用户名
     */
    public void forceLogout(String username) {
        Optional<String> sessionId = userCache.getData(username);
        if (sessionId.isPresent()) {
            tokenCache.clearData(sessionId.get());
            userCache.clearData(username);
        }

        // 发布用户退出事件
        userEventPublish.forceLogout(username);
    }

    /**
     * 校验用户登录状态，未登录时报错
     *
     * @param sessionId 登录的session id
     * @param token     token信息
     */
    public void auth(String sessionId, String token) {
        Optional<User> userData = tokenCache.getData(sessionId);
        if (userData.isPresent() && token.equals(userData.get().getToken())) {
            return;
        }
        throw new AuthFailedException();
    }
}
